package com.wh.usercenter3.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;
import com.google.gson.reflect.TypeToken;
import com.wh.usercenter3.constant.CodeConstant;
import com.wh.usercenter3.exception.BaseException;
import com.wh.usercenter3.mapper.TeamMapper;
import com.wh.usercenter3.mapper.UserMapper;
import com.wh.usercenter3.pojo.Score;
import com.wh.usercenter3.pojo.Team;
import com.wh.usercenter3.pojo.User;
import com.wh.usercenter3.pojo.vo.NewTeamVo;
import com.wh.usercenter3.pojo.vo.NewUserVo;
import com.wh.usercenter3.service.UserService;
import com.wh.usercenter3.util.AlgorithmUtil;
import com.wh.usercenter3.util.UserUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
* @author 18141
* @description 针对表【user(用户)】的数据库操作Service实现
* @createDate 2025-02-09 17:07:13
*/
@Service
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserMapper, User>
    implements UserService{

    @Resource
    private UserMapper userMapper;

    @Resource
    private TeamMapper teamMapper;

    /**
     * 根据标签查找user
     * @param tagList 标签列表
     * @return user列表
     */
    public List<NewUserVo> userByTags(List<String> tagList) {
        if (CollectionUtils.isEmpty(tagList)) {
            throw new BaseException(CodeConstant.CLIENT_ERR, "参数为空");
        }

        // 先直接查出所有的user出来
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        List<User> userList = userMapper.selectList(queryWrapper);

        // 序列化工具
        Gson gson = new Gson();

        // 过滤不符合的user
        return userList.stream().filter(user -> {
            String userTag = user.getTag();
            if (StringUtils.isBlank(userTag)) {
                return false;
            }
            // 将一个json类型的字符串，反序列化成多个String对象
            Set<String> userTagSet = gson.fromJson(userTag, new TypeToken<Set<String>>() {
            }.getType());
            // 将目标查询标签 循环和 当前用户的标签 比对
            for (String tag : tagList) {
                // 如果当前用户标签集合有不跟任意一个目标标签一样的则过滤掉
                if (!userTagSet.contains(tag)) return false;
            }
            // 保留
            return true;
        }).map(UserUtil::userToVo).collect(Collectors.toList());
    }

    /**
     * 根据用户id查找队伍
     * @param userId 用户id
     * @return team视图封装类
     */
    @Override
    public NewTeamVo teamByUserId(long userId) {
        // 查询条件
        QueryWrapper<Team> wrapper = new QueryWrapper<>();
        wrapper.eq("userId", userId);
        // 数据库
        Team team = teamMapper.selectOne(wrapper);
        if (team == null) {
            throw new BaseException(CodeConstant.SERVICE_ERR, "无数据或数据库操作失败");
        }
        // 封装
        NewTeamVo newTeamVo = new NewTeamVo();
        BeanUtils.copyProperties(team,newTeamVo);
        return newTeamVo;
    }

    /**
     * 根据标签推荐用户
     *
     * @param loginUser
     * @return
     */
    @Override
    public List<Long> recommendUser(User loginUser) {
        // 1.先提取所有的user的标签 3月16
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.select("id", "tag");
        List<User> userList = this.list(userQueryWrapper);
        if (userList.isEmpty()) throw new BaseException(CodeConstant.SERVICE_ERR, "数据库异常");

        // 2.将查来的对象，转换成map User user -> String[] userTag
        Gson gson = new Gson();
        Map<User, String[]> tagMap = null;
        try {
            tagMap = userList.stream().collect(Collectors.toMap(user->user, user -> {
                String tag = user.getTag();
                if (tag==null) {
                    return new String[0];
                }
                Set<String> tagSet = gson.fromJson(tag, new TypeToken<Set<String>>() {
                }.getType());
                return tagSet.toArray(new String[0]);
            }));
        } catch (Exception e) {
            throw new BaseException(CodeConstant.SERVICE_ERR, "提取字段失败");
        }

        // 3.维护一个N位数的动态数组  每个元素放一个里面存放userId和score的映射对象
        LinkedList<Score> topList = new LinkedList<>();

        // 5.将loginUser的tag提取成string列表
        String[] loginUserTag = new String[0];
        try {
            Set<String> tagSet = gson.fromJson(loginUser.getTag(), new TypeToken<Set<String>>() {}.getType());
            loginUserTag = tagSet.toArray(new String[0]);
        } catch (JsonSyntaxException e) {
            throw new BaseException(CodeConstant.SERVICE_ERR, "标签反序列化失败");
        }

        // 6.维护动态数组
        try {
            for (Map.Entry<User, String[]> user : tagMap.entrySet()) {
                AlgorithmUtil.sortTopList(topList, loginUserTag, user);
                // 如果动态数组的长度超过5就删除最后一个
                if (topList.size() > 5) {
                    topList.removeLast();
                }
            }
        } catch (Exception e) {
            throw new BaseException(CodeConstant.SERVICE_ERR, "动态数组维护异常");
        }

        // 7.脱敏返回
        return topList.stream().map(score -> {
            return score.getUser().getId();
        }).collect(Collectors.toList());
    }


}




